import { Component } from 'react';
import { clone } from 'lodash';
import './Heatmap.less';
import h337 from 'heatmap.js'

let name = '';
var heatmapInstance = null;
let timer = null;
let ps = null,
  $ps = null,
  psOrigin = null;
export default class Heatmap extends Component {

  constructor(props) {
    super(props);
    let t = this,
      p = t.props;
    t.state = {
      city: p.city || "杭州市",
      time: p.time,
      zoomLevel: 10,
      cityCenter: [120.18323, 30.31436],
      // playing: p.playing,
      // animate: p.animate,
      centrial: p.city == '杭州市' ? [
        [120.21882, 30.2878], [120.18711, 30.23947], [120.09733, 30.2572], [120.12254, 30.30903], [120.1909, 30.2301], [120.14383, 30.26498]
      ] : p.city == '嘉兴市' ? [[120.7725, 30.76069], [120.80843, 30.6854]] : [[120.58444, 30.00837], [120.53061, 30.0952]],
      points: [], //02偏移坐标
    };
    name = p.name;
    window[name] = null;
    this.dataCreate = this.dataCreate.bind(this);
    this.dataRender = this.dataRender.bind(this);
    this.heatMap = this.heatMap.bind(this);
    this.playingMap = this.playingMap.bind(this);
    this.cancelZoom = this.cancelZoom.bind(this);
  }

  componentWillMount() {
    let t = this,
      { state: { time } } = t;
  }

  dataCreate(hour) {
    let t = this;
    const { state: { centrial, cityCenter } } = t;
    let stations = centrial.map(item => {
      var val = Math.floor(Math.random() * 100);
      return {
        x: item[0],
        y: item[1],
        value: Math.floor(Math.random() * 10 + 90),
      }
    })
    let points = [];
    var max = 0;
    var len_center = 0, len_near = 0;
    switch (hour) {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      case 22:
      case 23:
        len_center = 200;
        len_near = 20;
        break;
      case 5:
      case 6:
        len_center = 400;
        len_near = 20;
        break;
      case 7:
      case 8:
      case 9:
      case 10:
      case 16:
      case 17:
      case 18:
        len_center = 500;
        len_near = 2000;
        break;
      case 11:
      case 12:
      case 13:
      case 14:
      case 15:
      case 19:
      case 20:
      case 21:
        len_center = 200;
        len_near = 1000;
        break;
      default:
        len_center = 0;
        len_near = 0;
        break;
    }

    while (len_center--) {
      var val = Math.floor(Math.random() * 50);
      max = Math.max(max, val);
      let disX = Math.random() - 0.5;
      let disY = Math.pow(-1, Math.floor(Math.random() * 10)) * Math.sqrt(0.25 - disX * disX) * Math.random();
      var point = {
        x: (disX / 5 + cityCenter[0]).toFixed(5) - 0,
        y: (disY / 5 + cityCenter[1]).toFixed(5) - 0,
        value: val
      };
      points.push(point);
    }
    while (len_near--) {
      var val = Math.floor(Math.random() * 50);
      max = Math.max(max, val);
      let disX = Math.random() - 0.5;
      let disY = Math.pow(-1, Math.floor(Math.random() * 10)) * Math.sqrt(0.25 - disX * disX) * Math.random();
      var point = {
        x: (disX + cityCenter[0]).toFixed(5) - 0,
        y: (disY + cityCenter[1]).toFixed(5) - 0,
        value: val
      };
      points.push(point);
    }
    psOrigin = points;
    this.state.points = points.concat(stations) //像素坐标
  }

  dataRender(callback) {
    const { state: { points } } = this;
    // now generate some random data
    let $points = points.map(item => {
      return {
        x: window[name].toScreenCoordinate(item.x + ',' + item.y)[0],
        y: window[name].toScreenCoordinate(item.x + ',' + item.y)[1],
        value: item.value,
      }
    })
    this.setState({ $points }, function () { callback() })
  }

  heatMap() {
    let t = this,
      { state: { points, $points } } = t;
    // heatmap data format
    var data = {
      max: 100,
      data: $points//[{x:10,y:10,value: 40}]//t.dataRender(width, height)[1]
    };
    // if you have a set of datapoints always use setData instead of addData
    // for data initialization
    heatmapInstance.setData(data);
  }

  playingMap() {
    let t = this,
      { state: { points }, dataRender, heatMap } = t;
    timer = setInterval(() => {
      ps = ps == null ? clone(points, true) : clone($ps, true);
      $ps = null;
      $ps = ps.map(item => {
        return {
          x: item.x + parseFloat((Math.random() * 2 - 1) * 0.0005),
          y: item.y + parseFloat((Math.random() * 2 - 1) * 0.0005),
          value: item.value + parseFloat((Math.random() * 2 - 1) * 5)
        }
      });
      t.setState({ points: $ps }, () => {
        dataRender(heatMap)
      })
    }, 1000)
  }
  cancelZoom(e) {
    let { state: { zoomLevel } } = this;
    if (e.wheelDeltaY > 0) {
      if (zoomLevel >= 11) {
        if (e.stopPropagation) {//这是取消冒泡
          e.stopPropagation();
        } else {
          e.cancelBubble = true;
        };
      }
    } else {
      if (8 >= zoomLevel) {
        if (e.stopPropagation) {//这是取消冒泡
          e.stopPropagation();
        } else {
          e.cancelBubble = true;
        };
      }
    }
  }

  render() {
    return (
      <div className="mod-heatmap">
        <div id="mapbar"></div>
        <div className="heatmap" ref="heatmap"></div>
      </div>
    );
  }
  componentDidMount() {
    const { dataCreate, dataRender, heatMap, cancelZoom, state: { city, time, zoomLevel } } = this;
    let width = window.innerWidth,
      height = window.innerHeight,
      t = this;
    window[name] = new Maplet("mapbar");
    let $rend = () => {
      let $time = time,
        $year = $time.getFullYear(),
        $month = $time.getMonth() + 1,
        $day = $time.getDate();
      if ($year >= 2015 || $year <= 2016) {
        if ($month >= 6 && $year == 2015) {
          dataCreate($time.getHours());
          dataRender(heatMap);
        } else if ($month <= 5 && $year == 2016) {
          if ($month == 5 && $day > 21) {
            heatmapInstance.setData({ data: [] })
          } else {
            dataCreate($time.getHours());
            dataRender(heatMap);
          }
        } else {
          heatmapInstance.setData({ data: [] })
        }
      } else {
        heatmapInstance.setData({ data: [] })
      }
    }
    switch (city) {
      case '杭州市':
        window[name].centerAndZoom(new MPoint(120.18323, 30.31436), zoomLevel);
        t.setState({ city: city, cityCenter: [120.18323, 30.31436] }, () => {
          $rend()
        });
        break;
      case '嘉兴市':
        window[name].centerAndZoom(new MPoint(120.76488, 30.74098), zoomLevel);
        t.setState({ city: city, cityCenter: [120.76488, 30.74098] }, () => {
          $rend()
        });
        break;
      case '绍兴市':
        window[name].centerAndZoom(new MPoint(120.59973, 29.98929), zoomLevel);
        t.setState({ city: city, cityCenter: [120.59973, 29.98929] }, () => {
          $rend()
        });
        break;
      default:
        break;
    }
    window[name].addControl(new MStandardControl());
    window[name].resize(width - 264, height - 229);
    // minimal heatmap instance configuration
    heatmapInstance = h337.create({
      // only container is required, the rest will be defaults
      container: t.refs.heatmap,
      radius: 80,
      maxOpacity: .5,
      minOpacity: 0,
      blur: .75,
      // gradient: {
      //   // enter n keys between 0 and 1 here
      //   // for gradient color customization
      //   '.5': 'green',
      //   '.8': 'yellow',
      //   '.95': 'red'
      // }
    });
    heatmapInstance._renderer.canvas.height = height - 229;
    heatmapInstance._renderer._height = height - 229;
    document.getElementById('MapContainer').appendChild(t.refs.heatmap);
    MEvent.addListener(window[name], "pan", function (ev) {
      dataRender(heatMap);
    });
    MEvent.addListener(window[name], "zoom", function (ev) {
      t.setState({ zoomLevel: ev })
      dataRender(heatMap);
    });
    let LayerDrawMap = document.getElementById('LayerDrawMap');
    LayerDrawMap.addEventListener('mousewheel', cancelZoom);
    setTimeout(dataRender(heatMap), 300);
  }

  componentWillReceiveProps(nextProps) {
    let rend = () => {
      let $time = nextProps.time,
        $year = $time.getFullYear(),
        $month = $time.getMonth() + 1,
        $day = $time.getDate();
      if ($year >= 2015 || $year <= 2016) {
        if ($month >= 6 && $year == 2015) {
          dataCreate($time.getHours());
          dataRender(heatMap);
        } else if ($month <= 5 && $year == 2016) {
          if ($month == 5 && $day > 21) {
            heatmapInstance.setData({ data: [] })
          } else {
            dataCreate($time.getHours());
            dataRender(heatMap);
          }
        } else {
          heatmapInstance.setData({ data: [] })
        }
      } else {
        heatmapInstance.setData({ data: [] })
      }
    }
    let t = this,
      { state: { points, city, time }, dataCreate, dataRender, heatMap } = t;
    if (city != nextProps.city) {
      switch (nextProps.city) {
        case '杭州市':
          window[name].centerAndZoom(new MPoint(120.18323, 30.31436), 10);
          t.setState({
            city: nextProps.city,
            cityCenter: [120.18323, 30.31436],
            centrial: [
              [120.21882, 30.2878], [120.18711, 30.23947], [120.09733, 30.2572], [120.12254, 30.30903], [120.1909, 30.2301], [120.14383, 30.26498]
            ]
          }, () => {
            rend()
          });
          break;
        case '嘉兴市':
          window[name].centerAndZoom(new MPoint(120.76488, 30.74098), 10);
          t.setState({
            city: nextProps.city,
            cityCenter: [120.76488, 30.74098],
            centrial: [[120.7725, 30.76069], [120.80843, 30.6854]],
          }, () => {
            rend()
          });
          break;
        case '绍兴市':
          window[name].centerAndZoom(new MPoint(120.59973, 29.98929), 10);
          t.setState({
            city: nextProps.city,
            cityCenter: [120.59973, 29.98929],
            centrial: [[120.58444, 30.00837], [120.53061, 30.0952]],
          }, () => {
            rend()
          });
          break;
        default:
          break;
      }
    }
    if (time != nextProps.time) {
      t.setState({ time: nextProps.time }, () => {
        rend()
      })
    }
    if (nextProps.action == 'playing') {
      if (nextProps.playing) {
        t.playingMap();
      } else {
        clearInterval(timer);
        timer = null;
      }
    } else if (nextProps.action == 'cancel') {
      clearInterval(timer);
      timer = null;
      t.setState({ points: psOrigin }, () => {
        dataRender(heatMap)
      })
    }
  }

}
